#!/usr/sbin/rsct/perl5/bin/perl 
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1999,2002 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# "@(#)99   1.16   src/rsct/registry/cli/bin/chsrcolnm.perl, srcli, rsct_rpyxh, rpyxht1f3 2/22/01 16:25:37"
######################################################################
#                                                                    #
# Module: chsrcolnm                                                  #
#                                                                    #
# Purpose:                                                           #
#   chsrcolnm - Changes names of columns in a System Registry table. #
#                                                                    #
# Syntax:                                                            #
#   chsrcolnm [-h][-TV] Table Old_column=New_column ...              #
#                                                                    #
# Flags:                                                             #
#   -h  Help - writes this command's usage statement to stdout       #
#   -T  Trace - writes this program's trace messages to stderr       #
#   -V  Verbose - writes this program's verbose messages to stderr   #
#                                                                    #
# Operands:                                                          #
#   Table   The name of the table that you wish to modify. The Table #
#           operand can contain a relative or absolute path name.    #
#   Old_column The name of the column whose name you wish to change. #
#           The name must match one of the column names previously   #
#           defined in this tables' metadata.                        #
#   New_column The new name to be assigned to the column. Must be    #
#           considered a valid column name (alphanumeric characters  #
#           and underscores only.)                                   #
#   More than one Old_column=New_column pair can be specified.       #
#                                                                    #
# Description:                                                       #
#   The chsrcolnm command allows you to change the names of columns  #
#   in the specified System Registry table. Use this command to      #
#   change the metadata associated with the table's column           #
#   definition.                                                      #
#                                                                    #
#   Column names must be unique to the table. Valid column names     #
#   start with a letter and can contain alphanumeric characters and  #
#   underscores. It is suggested that OO naming conventions be used, #
#   for example NodeName instead of node_name.                       #
#                                                                    #
#   Using multiple Old_column=New_column pairs on the command line is#
#   equivalent to calling the command once for each pair. Column     #
#   names must be unique to a table.                                 #
#                                                                    #
#   Use the lssrtbldef or lssrtbl command to get a current column    #
#   definition list for the specified table.                         #
#                                                                    #
#   System column and primary key column names can not be changed.   #
#                                                                    #
# Exit Values:                                                       #
#   0  SR_CLI_SUCCESS        Command completed successfully.         #
#   1  SR_CLI_REGISTRY_ERROR Command terminated due to an underlying #
#                            System Registry error.                  #
#   2  SR_CLI_ERROR          Command terminated due to an underlying #
#                            error in the command script.            #
#   3  SR_CLI_BAD_OPERAND    Command terminated due to user          #
#                            specifying a bad operand.               #
#   4  SR_CLI_BAD_FLAG       Command terminated due to user          #
#                            specifying an invalid flag.             #
#   5  SR_CLI_USER_ERROR     Command terminated due to a user error. #
#                            For example specifying an undefined     #
#                            table to be modified.                   #
#                                                                    #
# Examples:                                                          #
#   To change the name of column Name in  /samples/table1            #
#   chsrcolnm /samples/table1 Name=FullName                          #
#                                                                    #
#   To change the name of columns Name and ID in table1 when         #
#   CT_SR_HOME is set to /samples, enter:                            #
#   chsrcolnm table1 Name=FullName ID=FullID                         #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#                                                                    #
# Outputs:                                                           #
#   stdout - messages during execution and Verbose output            #
#   stderr - error messages, trace and verbose messages              #
#                                                                    #
# External Ref:                                                      #
#   Commands: $LSMSG                                                 #
#   Extensions:  CT::SR.pm CT::CT.pm CT::SRrc.pm                     #
#   Perl library routines: Getopts::Std                              #
#   SR cli routines: : SR_cli_utils.pm - init_session,               #
#      $DEFAULT_GLOBAL_MOUNT_POINT, printCEMsg, set_session_variables#
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   000929 HGJ 38317: Initial delivery.                              #
#                                                                    #
######################################################################

#--------------------------------------------------------------------#
#                                                                    #
# General Program Flow/Logic:                                        #
#                                                                    #
# A: Parse command line - get table name and input file              #
# B: Initialise session with registry, including changing the        #
#    current directory if a relative path name is given (use value   #
#    given in CT_SR_HOME)                                            #
# C: Open file to be edited - exit if it won't open                  #
# D: Call CT::SR::change_column_name once for every column name to be#
#    changed.                                                        #
# E: Close session table and tree                                    #
#                                                                    #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included libraries and extensions                                  #
#--------------------------------------------------------------------#
use lib "/usr/sbin/rsct/pm";
use locale;
use Getopt::Std;

use CT_cli_utils qw(printIMsg
                    printEMsg
);

use CT::SRrc;
use CT::SR;
use SR_cli_utils qw(init_session 
                    printCEMsg 
                    $DEFAULT_GLOBAL_MOUNT_POINT
                    open_table  
                    set_session_variables
                    error_exit  
                    clean_session
);
use SR_cli_rc qw (:return_codes);


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
# Constants for use throughout program
$TRUE           = 1;
$FALSE          = 0;

$Verbose        = $FALSE;
$Trace          = $FALSE;

# Messaging variables
$PROGNAME       = "chsrcolnm";
$MSGCAT         = "srcli.cat";
$CTDIR          = "/usr/sbin/rsct";     # Cluster directory path
$CTBINDIR       = "$CTDIR/bin";         # Cluster Bin directory path
$LSMSG          = "$CTBINDIR/ctdspmsg"; # display message rtn.
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # Msg maps used by $LSMSG  

%Cleanup = ();                          # Hash of items to cleanup
                                        # {Session} $session to term

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
# Variables for use with extensions
my $Table_handle   = "";
my $Tree_handle    = "";                # initialised in init_session

# Other variables
my $Table_name     = "";
my $Table          = "";
my @Columns        = ();
my $Column_list    = "";
my $Old_column_name = "";
my $New_column_name = "";
my $Command_line_input = "";
my $Count          = 0;
my $Index          = 0;
my $Set_work_dir   = $FALSE;
my $Mount_point    = $DEFAULT_GLOBAL_MOUNT_POINT;
my $rc             = 0;                 # assume good return code
my $badrc          = 0;                 # assume good return code


#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
# TODO: Verbose messages in this routine that aren't using message
# maps are trace statements. When trace facilities are available to
# the SR these will be changed. (feature 48401)

# Parse the command line, exit if there are errors
($rc, $Table_name, $Count, @Columns ) = parse_cmd_line();   

# Error messages handled in previous subroutine
($rc == 0) || error_exit($rc);

# parsing the data out later
if ($Verbose) {
    foreach (@Columns) {
        $Column_list .= "  $_\n";
    }
    $Command_line_input = "\"  $Table_name\n$Column_list\"";
    printIMsg("IMsgchsrcolnmCommandLineInput", $Command_line_input);
}


# Initialize Registry Library Connection
($Set_work_dir, $Table) = set_session_variables($Table_name);
($rc,$Tree_handle) = init_session($Set_work_dir);

# Assume relevant error messages handled in initSession
($rc == 0) || error_exit($rc);

# Add the tree handle to the cleanup hash
$Cleanup{Session} = $Tree_handle;


# Call CT::SR::open_table to open table to be edited 
($rc, $Table_handle) = open_table($Tree_handle, $Table, $Table_name,
                        SR_METADATA);                   

($rc == 0) || error_exit($rc);
# Add the table handle to the cleanup hash
push @{$Cleanup{Tables}}, $Table_handle;


# Call CT::SR::change_column_name for each column given 

$Verbose && printIMsg("IMsgchsrcolnmTableName", $Table_name, $Table);

for ($Index = 0; $Index < $Count; $Index++) {
    ($Old_column_name, $New_column_name) = 
                        split /=/, $Columns[$Index];

#    $Verbose && printIMsg("IMsgchsrcolnmChangingNames", 
#                       $Old_column_name, $New_column_name);

    $Trace && print STDERR "Calling SR::change_column_name $Old_column_name=$New_column_name\n";
    $rc = CT::SR::change_column_name($Table_handle, $Old_column_name, 
                        $New_column_name);
    $Trace && 
        print STDERR "CT::SR::change_column_name return code: $rc\n";

    # Check result of previous call 
    $rc = error_check("sr_change_column_name", $rc, $Table_name);
    ($rc == 0 || $rc == SR_CLI_USER_ERROR) || error_exit($rc);
    # Save the first bad return code
    if (($rc != 0) && ($badrc == 0)) { $badrc = $rc; }
}

($badrc == 0) || error_exit($badrc);

# Clean up registry library connection including all trees and tables
$rc = clean_session($Tree_handle, $Mount_point, $Table_handle);

# Reset Cleanup hash for final error check
%Cleanup = ();
($rc == 0) || error_exit($rc);

# Return code is 0 if the code reaches this point
exit $rc;

#--------------------------------------------------------------------#
# End Main Code                                                      #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# parse_cmd_line:                                                    #
#   Uses getopts() to grab flags on the command line. Do a rough     #
#   parse on the command line input, checking for the corrent        #
#   number and format of operands. Display help if requested.        #
#                                                                    #
# Parameters:                                                        #
#   None. See Global variables below                                 #
#                                                                    #
# Return values:                                                     #
#   $local_rc   - local return code                                  #
#   $table_name - table name to be added                             #
#   $count      - number of columns to be changed                    #
#   @columns    - array of old and new column names from input       #
#                                                                    #
# Global Variables Modified:                                         #
#   $Trace             output   True (-T) turn Trace mode on.        #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#--------------------------------------------------------------------#
sub parse_cmd_line
{
# Set up local variables
my $local_rc = 0;
my @columns = ();
my $table_name = "";
my $count = 0;
my %opts = ();

# Grab the input flags from the command line
if (getopts('hTV',\%opts) == 0) {         
    printCEMsg("EMsgSRcliInvalidFlag");
    print_usage();
    return SR_CLI_BAD_FLAG;
}                  

if (defined $opts{h}) {   # print usage and exit
    print_usage();
    exit(0);    # exit quickly
}

# Set Trace flag if requested
if (defined $opts{T}) {
    $Trace = $TRUE;
}

# Set Verbose flag if requested
if (defined $opts{V}) {
    $Verbose = $TRUE;
}

# Get table name from input
$table_name = shift @ARGV;
if ((!$table_name ) || ($table_name =~ /=/)) {
    printCEMsg("EMsgSRcliNoTableName");
    print_usage();
    return SR_CLI_BAD_OPERAND;
}

if (!@ARGV) {
    printCEMsg("EMsgSRcliNoColumnData");
    print_usage();
    return SR_CLI_BAD_OPERAND;
}

# Initialise variables for processing the command line data
# TODO: need to look into transactions so the guarantee can be made
# that all the changes are completed or not, instead of just
# some. This will not be until Phase 9 (feature 49516)

while (@ARGV) {
    my $temp = shift @ARGV;
    if (($temp !~ /=/) || ($temp =~ /==/)){
        printEMsg("EMsgchsrcolnmInvalidOperandFormat", $temp);
        print_usage();
        return SR_CLI_BAD_OPERAND;
    }
    $columns[$count++] = $temp;
}

return($local_rc, $table_name, $count, @columns);
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# error_check:                                                       #
#   Checks the return code from the SR function.  If an error is     #
#   detected appropriate error messages will be displayed and        #
#   SR CLI return code set.                                          #
#                                                                    #
# Parameters:                                                        #
#   $sr_function  - Name of the SR function that was called and      #
#                   whose error code we are checking.                #
#   $sr_rc        - SR function return code.                         #
#   $table_name   - Name of the table trying to create.              #
#                                                                    #
# Return values:                                                     #
#   None.                                                            #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub error_check
{
my ($sr_function, $sr_rc, $table_name) = @_; 
my $rc = 0;

if ($sr_rc != 0) { 
    if ($sr_rc == SR_NO_PERMISSION) {
        printEMsg("EMsgchsrcolnmNoPermission", $table_name);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_NO_TABLE) {
        printCEMsg("EMsgSRcliNoTable", $table_name);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_NO_COLUMN) {
        # All this to display quotes around the column name
        # in the msg map
        $Old_column_name = "\"\'$Old_column_name\'\"";  
        printEMsg("EMsgchsrcolnmInvalidColumn", $Old_column_name,
            $table_name);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_ILLEGAL_OPERATION) {
        printEMsg("EMsgchsrcolnmIllegalOperation");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_NULL_POINTER) {
        printEMsg("EMsgchsrcolnmNullPointer");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_CONNECTION_LOST) {
        # Quit out, this is too serious to continue
        printCEMsg("EMsgSRcliConnectionLost");
        $rc = SR_CLI_REGISTRY_ERROR;
    }
    else {
        # All this to display quotes around the column name 
        # in the msg map
        $Old_column_name = "\"\'$Old_column_name\'\"";  
        printEMsg("EMsgchsrcolnmErrorChangingName", $Old_column_name);
        printCEMsg("EMsgSRcliSRCommandFailure",
             "sr_change_column_name", $sr_rc);
        $rc = SR_CLI_REGISTRY_ERROR;
    }
}

return $rc;
}   # end error_check


#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#   See this command's prologue syntax section for current usage.    #
#--------------------------------------------------------------------#
sub print_usage
{
printIMsg("IMsgchsrcolnmUsage");
}   # end print_usage


#--------------------------------------------------------------------#
# End File                                                           #
#--------------------------------------------------------------------#
